/**
 * 深度验证UT规则 - 函数级别分析
 * 
 * 分析每个测试函数的具体实现模式，而不仅仅是文件级别统计
 */

const fs = require('fs');
const path = require('path');

const stats = {
    totalTestFiles: 0,
    totalTestFunctions: 0,
    
    // 每个测试函数的统计
    testFunctions: {
        withMock: 0,                    // 使用Mock
        withoutMock: 0,                 // 不使用Mock
        withSmartPointer: 0,            // 使用智能指针
        withStackObject: 0,             // 使用栈对象
        withRawPointer: 0,              // 使用裸指针
        withNew: 0,                     // 使用new
        
        // Mock相关
        mockPatterns: {
            definesMockClass: 0,        // 在测试函数内定义Mock类
            usesMakeShared: 0,          // std::make_shared<MockXxx>
            usesExpectCall: 0,          // EXPECT_CALL
            usesWillOnce: 0,            // WillOnce
            usesWillRepeatedly: 0,      // WillRepeatedly
            usesDoAll: 0,               // DoAll
            usesSetArgReferee: 0,       // SetArgReferee
            usesInvoke: 0,              // Invoke lambda
        },
        
        // 对象创建模式
        objectCreation: {
            makeSharedPattern: 0,       // auto obj = std::make_shared<T>()
            sharedPtrNew: 0,            // std::shared_ptr<T>(new T())
            sptrMakeSptr: 0,            // sptr<T>::MakeSptr()
            stackObject: 0,             // T obj;
            rawNew: 0,                  // T* obj = new T()
        },
        
        // 测试结构
        structure: {
            hasComments: 0,             // 有注释说明
            hasArrange: 0,              // 明确的Arrange部分
            hasAct: 0,                  // 明确的Act部分
            hasAssert: 0,               // 明确的Assert部分
            multipleExpects: 0,         // 多个EXPECT
            singleExpect: 0,            // 单个EXPECT
        },
        
        // 复杂度
        complexity: {
            verySimple: 0,              // < 5行代码
            simple: 0,                  // 5-15行
            medium: 0,                  // 15-30行
            complex: 0,                 // > 30行
        }
    }
};

// 示例收集
const examples = {
    simplestTests: [],              // 最简单的测试
    mockWithSetArgReferee: [],      // 使用SetArgReferee的完整示例
    mockWithInvoke: [],             // 使用Invoke的完整示例
    stackObjectTests: [],           // 使用栈对象的测试
    smartPointerTests: [],          // 使用智能指针的测试
    complexMockTests: [],           // 复杂Mock场景
};

/**
 * 递归查找所有测试文件（包括各种命名）
 */
function findAllTestFiles(dir, maxDepth = 10, currentDepth = 0) {
    const testFiles = [];
    
    if (currentDepth > maxDepth) return testFiles;
    
    try {
        const items = fs.readdirSync(dir, { withFileTypes: true });
        
        for (const item of items) {
            if (!item.isDirectory()) {
                // 更宽泛的测试文件匹配
                if ((item.name.includes('test') || item.name.includes('Test')) && 
                    item.name.endsWith('.cpp')) {
                    testFiles.push(path.join(dir, item.name));
                }
                continue;
            }
            
            const fullPath = path.join(dir, item.name);
            
            // 跳过特定目录
            if (item.name.includes('node_modules') || 
                item.name.includes('.git') ||
                item.name.includes('out') ||
                item.name.includes('build')) {
                continue;
            }
            
            const subFiles = findAllTestFiles(fullPath, maxDepth, currentDepth + 1);
            testFiles.push(...subFiles);
        }
    } catch (err) {
        // Ignore
    }
    
    return testFiles;
}

/**
 * 提取文件中的所有测试函数
 */
function extractTestFunctions(content) {
    const functions = [];
    
    // 匹配TEST_F, HWTEST_F, TEST
    const testRegex = /(HWTEST_F|TEST_F|TEST)\s*\(\s*([^,]+)\s*,\s*([^,]+)\s*(?:,\s*[^)]+)?\s*\)\s*\{/g;
    
    let match;
    while ((match = testRegex.exec(content)) !== null) {
        const testType = match[1];
        const testClass = match[2].trim();
        const testName = match[3].trim();
        const startPos = match.index;
        const startBracePos = content.indexOf('{', startPos);
        
        // 找到对应的结束大括号
        let braceCount = 1;
        let endPos = startBracePos + 1;
        
        while (endPos < content.length && braceCount > 0) {
            if (content[endPos] === '{') braceCount++;
            if (content[endPos] === '}') braceCount--;
            endPos++;
        }
        
        const functionBody = content.substring(startBracePos + 1, endPos - 1);
        
        functions.push({
            type: testType,
            className: testClass,
            functionName: testName,
            body: functionBody,
            fullText: content.substring(startPos, endPos)
        });
    }
    
    return functions;
}

/**
 * 分析单个测试函数
 */
function analyzeTestFunction(func, filePath) {
    const body = func.body;
    const lines = body.split('\n').filter(l => l.trim() && !l.trim().startsWith('//')).length;
    
    stats.totalTestFunctions++;
    
    // 复杂度
    if (lines < 5) stats.testFunctions.complexity.verySimple++;
    else if (lines < 15) stats.testFunctions.complexity.simple++;
    else if (lines < 30) stats.testFunctions.complexity.medium++;
    else stats.testFunctions.complexity.complex++;
    
    // Mock相关
    const hasMock = /EXPECT_CALL|MOCK_METHOD|Mock\w+/.test(body);
    if (hasMock) stats.testFunctions.withMock++;
    else stats.testFunctions.withoutMock++;
    
    if (/EXPECT_CALL/.test(body)) stats.testFunctions.mockPatterns.usesExpectCall++;
    if (/\.WillOnce/.test(body)) stats.testFunctions.mockPatterns.usesWillOnce++;
    if (/\.WillRepeatedly/.test(body)) stats.testFunctions.mockPatterns.usesWillRepeatedly++;
    if (/DoAll\s*\(/.test(body)) stats.testFunctions.mockPatterns.usesDoAll++;
    if (/SetArgReferee/.test(body)) {
        stats.testFunctions.mockPatterns.usesSetArgReferee++;
        
        // 收集SetArgReferee示例
        if (examples.mockWithSetArgReferee.length < 5) {
            examples.mockWithSetArgReferee.push({
                file: filePath,
                test: `${func.className}::${func.functionName}`,
                body: func.fullText.length > 1000 ? func.fullText.substring(0, 1000) + '...' : func.fullText
            });
        }
    }
    if (/Invoke\s*\(/.test(body)) {
        stats.testFunctions.mockPatterns.usesInvoke++;
        
        // 收集Invoke示例
        if (examples.mockWithInvoke.length < 5) {
            examples.mockWithInvoke.push({
                file: filePath,
                test: `${func.className}::${func.functionName}`,
                body: func.fullText.length > 1000 ? func.fullText.substring(0, 1000) + '...' : func.fullText
            });
        }
    }
    
    // 对象创建模式
    if (/std::make_shared<[^>]+>\s*\(/.test(body)) {
        stats.testFunctions.objectCreation.makeSharedPattern++;
        stats.testFunctions.withSmartPointer++;
        
        if (/std::make_shared<Mock\w+>/.test(body)) {
            stats.testFunctions.mockPatterns.usesMakeShared++;
        }
    }
    
    if (/sptr<[^>]+>::MakeSptr/.test(body)) {
        stats.testFunctions.objectCreation.sptrMakeSptr++;
        stats.testFunctions.withSmartPointer++;
    }
    
    if (/std::shared_ptr<[^>]+>\s*\(\s*new\s+/.test(body)) {
        stats.testFunctions.objectCreation.sharedPtrNew++;
        stats.testFunctions.withSmartPointer++;
    }
    
    // 栈对象检测（简化版）
    const stackObjectPattern = /^\s*[A-Z]\w+\s+\w+(?:\([^)]*\))?\s*;/gm;
    const stackMatches = body.match(stackObjectPattern);
    if (stackMatches && stackMatches.length > 0) {
        stats.testFunctions.objectCreation.stackObject++;
        stats.testFunctions.withStackObject++;
        
        // 收集栈对象示例
        if (!hasMock && lines < 10 && examples.stackObjectTests.length < 5) {
            examples.stackObjectTests.push({
                file: filePath,
                test: `${func.className}::${func.functionName}`,
                body: func.fullText.length > 500 ? func.fullText.substring(0, 500) + '...' : func.fullText
            });
        }
    }
    
    // 裸指针
    if (/\bnew\s+\w+/.test(body)) {
        stats.testFunctions.objectCreation.rawNew++;
        stats.testFunctions.withRawPointer++;
    }
    
    // 测试结构
    if (/\/\/.*[Aa]rrange|\/\/.*准备|\/\/.*初始化/.test(body)) stats.testFunctions.structure.hasArrange++;
    if (/\/\/.*[Aa]ct|\/\/.*执行|\/\/.*调用/.test(body)) stats.testFunctions.structure.hasAct++;
    if (/\/\/.*[Aa]ssert|\/\/.*验证|\/\/.*断言/.test(body)) stats.testFunctions.structure.hasAssert++;
    if (/\/\//.test(body)) stats.testFunctions.structure.hasComments++;
    
    const expectCount = (body.match(/EXPECT_/g) || []).length;
    if (expectCount > 1) stats.testFunctions.structure.multipleExpects++;
    if (expectCount === 1) stats.testFunctions.structure.singleExpect++;
    
    // 收集最简单的测试示例
    if (lines <= 5 && !hasMock && examples.simplestTests.length < 5) {
        examples.simplestTests.push({
            file: filePath,
            test: `${func.className}::${func.functionName}`,
            lines: lines,
            body: func.fullText
        });
    }
}

/**
 * 分析单个测试文件
 */
function analyzeTestFile(filePath) {
    try {
        const content = fs.readFileSync(filePath, 'utf-8');
        const functions = extractTestFunctions(content);
        
        for (const func of functions) {
            analyzeTestFunction(func, filePath);
        }
        
    } catch (err) {
        console.error(`Error analyzing ${filePath}: ${err.message}`);
    }
}

/**
 * 生成报告
 */
function generateReport() {
    const report = {
        summary: {
            totalTestFiles: stats.totalTestFiles,
            totalTestFunctions: stats.totalTestFunctions,
            avgFunctionsPerFile: (stats.totalTestFunctions / stats.totalTestFiles).toFixed(2)
        },
        
        mockUsage: {
            withMock: stats.testFunctions.withMock,
            withoutMock: stats.testFunctions.withoutMock,
            mockPercentage: ((stats.testFunctions.withMock / stats.totalTestFunctions) * 100).toFixed(2) + '%',
            
            patterns: {
                usesExpectCall: stats.testFunctions.mockPatterns.usesExpectCall,
                usesWillOnce: stats.testFunctions.mockPatterns.usesWillOnce,
                usesDoAll: stats.testFunctions.mockPatterns.usesDoAll,
                usesSetArgReferee: stats.testFunctions.mockPatterns.usesSetArgReferee,
                usesInvoke: stats.testFunctions.mockPatterns.usesInvoke,
                usesMakeSharedMock: stats.testFunctions.mockPatterns.usesMakeShared
            },
            
            percentages: {
                expectCall: ((stats.testFunctions.mockPatterns.usesExpectCall / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                setArgReferee: ((stats.testFunctions.mockPatterns.usesSetArgReferee / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                doAll: ((stats.testFunctions.mockPatterns.usesDoAll / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                invoke: ((stats.testFunctions.mockPatterns.usesInvoke / stats.totalTestFunctions) * 100).toFixed(2) + '%'
            }
        },
        
        objectCreation: {
            counts: stats.testFunctions.objectCreation,
            percentages: {
                makeShared: ((stats.testFunctions.objectCreation.makeSharedPattern / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                stackObject: ((stats.testFunctions.objectCreation.stackObject / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                sptrMakeSptr: ((stats.testFunctions.objectCreation.sptrMakeSptr / stats.totalTestFunctions) * 100).toFixed(2) + '%'
            }
        },
        
        complexity: {
            ...stats.testFunctions.complexity,
            percentages: {
                verySimple: ((stats.testFunctions.complexity.verySimple / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                simple: ((stats.testFunctions.complexity.simple / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                medium: ((stats.testFunctions.complexity.medium / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                complex: ((stats.testFunctions.complexity.complex / stats.totalTestFunctions) * 100).toFixed(2) + '%'
            }
        },
        
        structure: {
            ...stats.testFunctions.structure,
            percentages: {
                hasComments: ((stats.testFunctions.structure.hasComments / stats.totalTestFunctions) * 100).toFixed(2) + '%',
                hasArrange: ((stats.testFunctions.structure.hasArrange / stats.totalTestFunctions) * 100).toFixed(2) + '%'
            }
        },
        
        examples: {
            simplestTests: examples.simplestTests.slice(0, 3),
            mockWithSetArgReferee: examples.mockWithSetArgReferee.slice(0, 2),
            mockWithInvoke: examples.mockWithInvoke.slice(0, 2),
            stackObjectTests: examples.stackObjectTests.slice(0, 3)
        }
    };
    
    return report;
}

/**
 * 主函数
 */
function main() {
    console.log('🔍 开始深度验证UT规则（函数级别）...\n');
    
    const ohCodePath = path.join(__dirname, '../OHCode');
    
    if (!fs.existsSync(ohCodePath)) {
        console.error('❌ OHCode目录不存在！');
        process.exit(1);
    }
    
    console.log('📂 查找所有测试文件...');
    const testFiles = findAllTestFiles(ohCodePath);
    stats.totalTestFiles = testFiles.length;
    
    console.log(`✅ 找到 ${testFiles.length} 个测试文件\n`);
    console.log('📊 开始分析每个测试函数...\n');
    
    let processed = 0;
    const progressInterval = Math.max(1, Math.floor(testFiles.length / 20));
    
    for (const file of testFiles) {
        analyzeTestFile(file);
        processed++;
        
        if (processed % progressInterval === 0 || processed === testFiles.length) {
            const percent = ((processed / testFiles.length) * 100).toFixed(1);
            console.log(`  进度: ${processed}/${testFiles.length} (${percent}%) - 已分析${stats.totalTestFunctions}个测试函数`);
        }
    }
    
    console.log('\n✅ 分析完成！\n');
    console.log('📝 生成报告...\n');
    
    const report = generateReport();
    
    // 保存报告
    const reportPath = path.join(__dirname, '../UT_DEEP_VALIDATION.json');
    fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
    
    console.log(`✅ 详细报告已保存: ${reportPath}\n`);
    
    // 打印摘要
    console.log('━'.repeat(80));
    console.log('                   📊 函数级别深度分析');
    console.log('━'.repeat(80));
    console.log();
    
    console.log(`总测试文件: ${report.summary.totalTestFiles}`);
    console.log(`总测试函数: ${report.summary.totalTestFunctions}`);
    console.log(`平均每文件函数数: ${report.summary.avgFunctionsPerFile}\n`);
    
    console.log('1️⃣ Mock使用率（函数级别）:');
    console.log(`  - 使用Mock的测试函数: ${report.mockUsage.mockPercentage}`);
    console.log(`  - EXPECT_CALL: ${report.mockUsage.percentages.expectCall}`);
    console.log(`  - DoAll: ${report.mockUsage.percentages.doAll}`);
    console.log(`  - SetArgReferee: ${report.mockUsage.percentages.setArgReferee} ⚠️`);
    console.log(`  - Invoke: ${report.mockUsage.percentages.invoke}\n`);
    
    console.log('2️⃣ 对象创建模式（函数级别）:');
    console.log(`  - std::make_shared: ${report.objectCreation.percentages.makeShared}`);
    console.log(`  - 栈对象: ${report.objectCreation.percentages.stackObject}`);
    console.log(`  - sptr::MakeSptr: ${report.objectCreation.percentages.sptrMakeSptr}\n`);
    
    console.log('3️⃣ 测试函数复杂度:');
    console.log(`  - 非常简单(<5行): ${report.complexity.percentages.verySimple}`);
    console.log(`  - 简单(5-15行): ${report.complexity.percentages.simple}`);
    console.log(`  - 中等(15-30行): ${report.complexity.percentages.medium}`);
    console.log(`  - 复杂(>30行): ${report.complexity.percentages.complex}\n`);
    
    console.log('4️⃣ 测试结构:');
    console.log(`  - 有注释: ${report.structure.percentages.hasComments}`);
    console.log(`  - 明确AAA结构: ${report.structure.percentages.hasArrange}\n`);
    
    console.log('━'.repeat(80));
    console.log();
    
    // 打印最简单的测试示例
    if (examples.simplestTests.length > 0) {
        console.log('📝 最简单的测试示例（<5行）：\n');
        console.log(examples.simplestTests[0].body);
        console.log('\n' + '─'.repeat(80) + '\n');
    }
}

// 运行
main();

